# Context switch
#
#   void swtch(struct context *old, struct context *new);
#
# Save current registers in old, load from new.
# Switches kernel stack

.globl swtch
swtch:
        # 保存旧进程的callee-saved寄存器到old context
        sd ra, 0(a0)   # 返回地址
        sd sp, 8(a0)   # 栈指针
        sd s0, 16(a0)  # 保存s0-s11
        sd s1, 24(a0)
        sd s2, 32(a0)
        sd s3, 40(a0)
        sd s4, 48(a0)
        sd s5, 56(a0)
        sd s6, 64(a0)
        sd s7, 72(a0)
        sd s8, 80(a0)
        sd s9, 88(a0)
        sd s10, 96(a0)
        sd s11, 104(a0)

        # 从new context恢复寄存器
        ld ra, 0(a1)   # 加载新进程的返回地址
        ld sp, 8(a1)   # 加载新进程的栈指针
        ld s0, 16(a1)  # 恢复s0-s11
        ld s1, 24(a1)
        ld s2, 32(a1)
        ld s3, 40(a1)
        ld s4, 48(a1)
        ld s5, 56(a1)
        ld s6, 64(a1)
        ld s7, 72(a1)
        ld s8, 80(a1)
        ld s9, 88(a1)
        ld s10, 96(a1)
        ld s11, 104(a1)

        ret            # 返回到新进程的ra（返回地址）
